package persistent

import (
	"context"
	"time"

	"gorm.io/gorm"
)

// TimeoutNodeInfo 超时节点信息
// 包含节点、工作流和工作流模板的相关信息
type TimeoutNodeInfo struct {
	// 节点信息
	NodeID        string    `gorm:"column:node_id"`
	NodeStatus    int       `gorm:"column:node_status"`
	NodeCreatedAt time.Time `gorm:"column:node_created_at"`

	// 工作流信息
	WorkflowID string `gorm:"column:workflow_id"`

	// 工作流模板信息
	WorkflowTemplateID    string `gorm:"column:workflow_template_id"`
	TimeoutAlertHours     int    `gorm:"column:timeout_alert_hours"`
}

// TimeoutNodeWithTasks 超时节点及其审批任务信息
// 通过一次查询获取节点和相关审批任务的完整信息，避免N+1查询问题
type TimeoutNodeWithTasks struct {
	// 节点信息
	NodeID        string    `gorm:"column:node_id"`
	NodeStatus    int       `gorm:"column:node_status"`
	NodeCreatedAt time.Time `gorm:"column:node_created_at"`

	// 工作流信息
	WorkflowID string `gorm:"column:workflow_id"`

	// 工作流模板信息
	WorkflowTemplateID    string `gorm:"column:workflow_template_id"`
	TimeoutAlertHours     int    `gorm:"column:timeout_alert_hours"`

	// 审批任务信息
	TaskID     string `gorm:"column:task_id"`
	ReviewerID string `gorm:"column:reviewer_id"`
	TaskStatus int    `gorm:"column:task_status"`
}

// TimeoutNodesClient 超时节点查询客户端
type TimeoutNodesClient struct {
	db *gorm.DB
}

// NewTimeoutNodesClient 创建超时节点查询客户端
func NewTimeoutNodesClient(db *gorm.DB) *TimeoutNodesClient {
	return &TimeoutNodesClient{db: db}
}

// QueryTimeoutNodes 查询所有超时的节点
// 功能说明:
//   1. 查询所有超时的节点基本信息
//   2. 查询条件：节点状态为待审批、工作流模板配置了超时提醒时间、节点创建时间超过配置的超时时间
//
// 参数说明:
//   - ctx: 上下文对象
//
// 返回值:
//   - result: 超时节点信息列表
//   - err: 查询过程中的错误信息
func (c *TimeoutNodesClient) QueryTimeoutNodes(ctx context.Context) (result []TimeoutNodeInfo, err error) {
	// 构建查询条件
	// 1. 节点状态为待审批（status=1）
	// 2. 工作流模板配置了超时提醒时间（timeout_alert_hours > 0）
	// 3. 节点创建时间超过了配置的超时时间
	db := c.db.WithContext(ctx).
		Scopes(TimeoutNodesView).
		Where("node.status = ?", 1). // 待审批状态
		Where("workflow_template.timeout_alert_hours > 0"). // 配置了超时提醒
		Where("node.created_at < DATE_SUB(NOW(), INTERVAL workflow_template.timeout_alert_hours HOUR)") // 超时判断

	// 执行查询
	err = db.
		Select(`
			node.id AS node_id,
			node.status AS node_status,
			node.created_at AS node_created_at,
			workflow.id AS workflow_id,
			workflow_template.id AS workflow_template_id,
			workflow_template.timeout_alert_hours
		`).
		Find(&result).Error

	return result, err
}

// QueryTimeoutNodesWithTasks 查询所有超时的节点及其审批任务
// 功能说明:
//   1. 通过一次查询获取所有超时节点及其相关的审批任务信息
//   2. 避免N+1查询问题，提升查询性能
//   3. 查询条件与QueryTimeoutNodes相同，但同时获取审批任务数据
//
// 参数说明:
//   - ctx: 上下文对象
//
// 返回值:
//   - result: 超时节点及审批任务信息列表
//   - err: 查询过程中的错误信息
func (c *TimeoutNodesClient) QueryTimeoutNodesWithTasks(ctx context.Context) (result []TimeoutNodeWithTasks, err error) {
	// 构建查询条件
	// 1. 节点状态为待审批（status=1）
	// 2. 工作流模板配置了超时提醒时间（timeout_alert_hours > 0）
	// 3. 节点创建时间超过了配置的超时时间
	// 4. 审批任务状态为审核中（node_reviewer_task.status = 1）
	db := c.db.WithContext(ctx).
		Scopes(TimeoutNodesWithTasksView).
		Where("node.status = ?", 1). // 待审批状态
		Where("workflow_template.timeout_alert_hours > 0"). // 配置了超时提醒
		Where("node.created_at < DATE_SUB(NOW(), INTERVAL workflow_template.timeout_alert_hours HOUR)"). // 超时判断
		Where("node_reviewer_task.status = ?", 1) // 审核中的任务

	// 执行查询
	err = db.
		Select(`
			node.id AS node_id,
			node.status AS node_status,
			node.created_at AS node_created_at,
			workflow.id AS workflow_id,
			workflow_template.id AS workflow_template_id,
			workflow_template.timeout_alert_hours,
			node_reviewer_task.id AS task_id,
			node_reviewer_task.reviewer_id,
			node_reviewer_task.status AS task_status
		`).
		Find(&result).Error

	return result, err
}